﻿<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>Bordecal.ImportsSorter add-in for Visual Studio</title>
	<base target="_blank" />
	<style type="text/css">
		body
		{
			font-size: 80%;
			color: #000000;
			font-family: verdana, arial, helvetica, sans-serif;
			background-color: #ffffff;
		}
		table
		{
			font-size: 100%;
			color: #000000;
			font-family: verdana, arial, helvetica, sans-serif;
			background-color: #ffffff;
		}
		th
		{
			background-color: #dcdcdc;
			font-weight: bold;
			color: #000080;
		}
		td
		{
			vertical-align: top;
		}
		h1
		{
			font-weight: bold;
			font-size: 110%;
			color: #000080;
		}
		h2
		{
			margin-top: 2.5em;
			font-weight: bold;
			font-size: 100%;
			margin-bottom: 0.7em;
			color: #000080;
		}
		p
		{
			margin-top: 0px;
			margin-bottom: 1em;
		}
		ul
		{
			margin-left: 20px;
			margin-top: 0px;
			margin-bottom: 0px;
		}
		li
		{
			margin-bottom: 0.7em;
		}
		li.tight
		{
			margin-bottom: 0;
		}
		pre
		{
			margin-top: 0px;
			margin-bottom: 0px;
		}
		a
		{
			color: #000080;
		}
		.codeKeyword
		{
			font-family: Courier New, Courier;
			font-weight: bold;
			white-space: nowrap;
		}
	</style>
</head>
<body bgcolor="#ffffff">
	<a name="mainTitle"></a>
	<h1>
		Bordecal.ImportsSorter add-in for Visual Studio 2005</h1>
	<p>
		<a href="mailto:calinoiu@gmail.com?subject=Bordecal.ImportsSorter%20add-in">Nicole Calinoiu</a>
		<br />
		October 2005 (last edited July 2009)
	</p>
	<a name="tocTitle"></a>
	<h2>
		Table of contents</h2>
	<p>
		<a href="#introduction" target="_self">Introduction</a><br />
		<a href="#installation" target="_self">Installing the add-in</a><br />
		<a href="#updates" target="_self">Updates</a><br />
		<a href="#loadingAddin" target="_self">Loading the add-in</a><br />
		<a href="#configuringSorting" target="_self">Configuring the sorting behaviour</a><br />
		<a href="#sortingImports" target="_self">Sorting the imports/using directives in a file</a><br />
		<a href="#knownIssuesTitle" target="_self">Known issues</a>
	</p>
	<a name="introduction"></a>
	<h2>
		Introduction</h2>
	<p>
		Visual Studio 2005 introduced <a href="http://msdn2.microsoft.com/en-us/library/3shw4wa2">
			new functionality</a> for automatic generation of imports/using directives when
		types cannot be resolved. This is a great little addition to the coding UI, but
		it can pose a bit of a problem for the anal-retentive nit-pickers amongst us since
		the new directives simply get added to the end of the imports/using directive block.
		Of course, this causes no problem whatsoever for the compiler, but it's not particularly
		pretty either. (And &quot;pretty&quot; is, of course, the single most important
		goal for any code file. &lt;g&gt;)
	</p>
	<p>
		I happen to be rather picky about what my imports/using blocks look like. In particular,
		I like to sort the directives in alphabetical order by namespace within the following
		four groups:
	</p>
	<ul>
		<li>System namespace and descendants</li>
		<li>Microsoft namespace and descendants</li>
		<li>third party namespaces</li>
		<li>my own namespaces</li>
	</ul>
	<br />
	<p>
		In previous version of Visual Studio, maintaining this sequence wasn't too much
		extra work since I already had to scroll to top of a code file anyway to add a new
		directive. However, with the new automated directive insertion, scrolling to the
		top of the page just to sort the imports/using block manually after an automated
		directive addition started to feel very inconvenient. Unfortunately, the mere suspicion
		that my imports/using block might be out of sequence turned out to be a horrible
		distraction for me, and I was ending up doing a manual sort after each automated
		addition. After a few days of this nonsense, I figured it was about high time to
		automate the sorting, and the Bordecal.ImportsSorter add-in was born.
	</p>
	<a name="installation"></a>
	<h2>
		Installing the add-in</h2>
	<p>
		The current version of the add-in supports Visual Studio 2005 and 2008.</p>
	<p>
		The add-in comes packaged as an MSI, which can be downloaded from <a href="http://importssorter.codeplex.com/">
			http://importssorter.codeplex.com</a>. It must be installed as an administrator.
		The add-in files will be placed in the <span class="codeKeyword">%ALLUSERSPROFILE%\Application
			Data\Microsoft\MSEnvShared\Addins</span> directory, and the add-in will be available
		for all users on the machine.
	</p>
	<a name="updates"></a>
	<h2>
		Updates</h2>
	<p>
		The add-in does not perform automatic self-updates. New releases will be announced
		at <a href="http://importssorter.codeplex.com/">http://importssorter.codeplex.com</a>.</p>
	<a name="loadingAddin"></a>
	<h2>
		Loading the add-in <a name="loadingAddin"></a>
		<h2>
			Loading the add-in</h2>
		<p>
			The add-in is pre-configured to load automatically at Visual Studio startup. You
			can manage its startup beha menu item in Visual Studio. If you encounter problems
			attempting to load the add-in, verify that the following criteria are met:
		</p>
		<ul>
			<li>You are attempting to use the add-in in Visual Studio 2005 or 2008. </li>
			<li>Visual Studio is configured to permit add-ins to load, and the add-in registration
				file (<span class="codeKeyword">Bordecal.ImportsSorter.AddIn</span>) is located
				in one of the permitted add-in source directories. (Both of these configurations
				properties page of the Visual Studio options dialog.) </li>
			<li>The add-in assembly ( properties page of the Visual Studio 2005 options dialog.)
			</li>
			<li>The add-in assembly (<span class="codeKeyword">Bordecal.ImportsSorter.dll</span>)
				is fully trusted under your local code access security policy. (See the <b>To evaluate
					an assembly</b> topic at <a href="http://msdn2.microsoft.com/en-us/library/2bc0cxhc">
						http://msdn2.microsoft.com/en-us/library/2bc0cxhc</a> if you need instructions
				for verifying an assembly's CAS permissions.) </li>
		</ul>
		<a name="configuringSorting"></a>
		<h2>
			Configuring the sorting behaviour</h2>
		<p>
			The add item that should appear under your Visual Studio <span class="codeKeyword">Tools</span>
			menu once the add-in has been loaded. The configuration dialog allows you to specify
			the sorting order for the imports/using directives, the number of lines (if any)
			that will be inserted between sorting groups when the sorted directives are written
			back into your code files, and options for post-sorting display of the imports/using
			directives.
		</p>
		<p>
			If you&#39;re even remotely interested in using this add-in, I&#39;m guessing that
			you probably have a pretty good idea of what the sorting groups do. Just in case
			you&#39;re having any doubts, here are some examples of the results that various
			&quot;typical&quot; configurations would yield on a C# using directive block: g
			any doubts, here are some examples of the results that various &quot;typical&quot;
			configurations would yield on a C# using directive block:
		</p>
		<table border="1" cellpadding="10" cellspacing="0" width="90%">
			<colgroup>
				<col />
				<col align="center" />
				<col width="70%" />
			</colgroup>
			<thead>
				<tr>
					<th colspan="2">
						Configuration
					</th>
					<th rowspan="2" align="left">
						Sorting results
					</th>
				</tr>
				<tr>
					<th>
						Sorting groups
					</th>
					<th>
						Inter-group line count
					</th>
				</tr>
			</thead>
			<tbody>
				<tr>
					<td>
						System<br />
						Microsoft<br />
						&lt;All other namespaces&gt;<br />
						YourNamespace
					</td>
					<td>
						0
					</td>
					<td>
						<pre>using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Text;
using Microsoft.SqlServer;
using CrystalDecisions;
using YourNamespace;
using YourNamespace.Data;</pre>
					</td>
				</tr>
				<tr>
					<td>
						System<br />
						Microsoft<br />
						&lt;All other namespaces&gt;<br />
						YourNamespace
					</td>
					<td>
						1
					</td>
					<td>
						<pre>using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Text;

using Microsoft.SqlServer;

using CrystalDecisions;

using YourNamespace;
using YourNamespace.Data;</pre>
					</td>
				</tr>
				<tr>
					<td>
						System<br />
						System.Data<br />
						Microsoft<br />
						&lt;All other namespaces&gt;<br />
						YourNamespace
					</td>
					<td>
						1
					</td>
					<td>
						<pre>using System;
using System.Collections.Generic;
using System.Text;

using System.Data;
using System.Data.OleDb;

using Microsoft.SqlServer;

using CrystalDecisions;

using YourNamespace;
using YourNamespace.Data;</pre>
					</td>
				</tr>
				<tr>
					<td>
						System<br />
						Microsoft<br />
						&lt;All other namespaces&gt;
					</td>
					<td>
						1
					</td>
					<td>
						<pre>using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Text;

using Microsoft.SqlServer;

using CrystalDecisions;
using YourNamespace;
using YourNamespace.Data;</pre>
					</td>
				</tr>
				<tr>
					<td>
						&lt;All other namespaces&gt;
					</td>
					<td>
						1
					</td>
					<td>
						<pre>using CrystalDecisions;
using Microsoft.SqlServer;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Text;
using YourNamespace;
using YourNamespace.Data;</pre>
					</td>
				</tr>
			</tbody>
		</table>
		<br />
		<br />
		<p>
			Some of the configuration aspects that might not be immediately obvious are:
		</p>
		<ul>
			<li>The <span class="codeKeyword">&lt;All other namespaces&gt;</span> placeholder may
				be placed anywhere you like in the list.</li>
			<li>If you delete the <span class="codeKeyword">&lt;All other namespaces&gt;</span>
				placeholder, you can get it back by adding a sorting group with an empty namespace
				name.</li>
			<li>You may add both simple namespaces (<i>e.g.</i>: <span class="codeKeyword">System</span>)
				and compound namespaces (<i>e.g.</i>: <span class="codeKeyword">System.Data.SqlClient</span>)
				to the list. An imports/using directive will be placed in the group with the best
				(<i>i.e.</i>: longest) match found amongs the sorting groups list.</li>
			<li>There is no point in attempting to add aliases (<i>e.g.</i>: <span class="codeKeyword">
				foo = SomeNamespace</span>) or qualifiers (<i>e.g.</i>: <span class="codeKeyword">global::System</span>)
				to the list since they are ignored during sorting. (By the way, this is a deliberate
				design decision. If you would like to include aliases and/or qualifiers in the sorting,
				please let me know how and why, and I might consider adding support for your bit
				of weirdness to the add-in.)</li>
			<li>You may add a maximum of 50 sorting groups to the list.</li>
		</ul>
		<a name="sortingImports"></a>
		<h2>
			Sorting the imports/using directives in a file</h2>
		<p>
			To sort the imports/using directives in an open code file, display the code window
			shortcut menu (say, by right-clicking on the code editing surface), and select the
			<span class="codeKeyword">Sort the imports/using block</span> item. The exact labelling
			of this menu item will depend on the language of the code file for which it has
			been displayed, with the language-specific term for an imports/using directive being
			displayed. The language-specific labels are:
		</p>
		<table border="1" cellpadding="10" cellspacing="0">
			<thead>
				<tr>
					<th>
						Language
					</th>
					<th>
						Menu item label
					</th>
				</tr>
			</thead>
			<tbody>
				<tr>
					<td>
						C#
					</td>
					<td>
						<span class="codeKeyword">Sort the using block</span>
					</td>
				</tr>
				<tr>
					<td>
						J#
					</td>
					<td>
						<span class="codeKeyword">Sort the import block</span>
					</td>
				</tr>
				<tr>
					<td>
						VB.NET
					</td>
					<td>
						<span class="codeKeyword">Sort the Imports block</span>
					</td>
				</tr>
			</tbody>
		</table>
		<br />
		<p>
			If you would like to return to the pre-sorting state of your file, the entire sorting
			operation may be reversed in one undo step, via the usual undo mechanisms (<span
				class="codeKeyword">CTRL+z</span>, toolbar button, etc.).
		</p>
		<p>
			If your attempt at sorting the imports/using directives in a file appears to do
			nothing, you should check that there are no syntax problems before or amongst the
			directives since such issues can prevent the recognition of the intented directives
			in the code model.
		</p>
		<p>
			Interestingly enough, the C# code model is actually able to detect a <span class="codeKeyword">
				using</span> directive located anywhere outside a class declaration (even though
			such placement results in a compilation error). This has the somewhat convenient
			consequence that you may type a <span class="codeKeyword">using</span> directive
			at the end of your class or namespace code before running the sort, and it will
			still be sorted into the <span class="codeKeyword">using</span> block at the beginning
			of your file. Unfortunately, neither the VB nor the J# code models identify a similarly
			&quot;misplaced&quot; directive in their code elements collections, so this will
			only work in C#.
		</p>
		<a name="knownIssuesTitle"></a>
		<h2>
			Known issues</h2>
		<ul>
			<li>The sorting procedure doesn't deal with multi-line comments particularly elegantly.
				(It will either abandon or split them, depending on how and where the comment is
				started.) The main reason for this lack of support is that the VStudio code model
				doesn't identify comments as code elements, so they need to be parsed out manually.
				Handling this correctly is a bit of a pain, particularly when one considers the
				additional complexity involved in mapping a multi-line comment that doesn't start
				on a directive line to either the directive that preceded or follows it. Since I
				can't think of any reason why one would actually want to associate a multi-line
				comment with an imports/using directive, I didn't bother adding support for them.
				If you happen to have a good reason for adding multi-line comments to your imports/using
				directive blocks, please let me know, and I'll consider modifying the add-in to
				support them properly. </li>
			<li>Only C#, VB.NET, and J# are supported so far. It looks like the code model for C++
				doesn't identify <span class="codeKeyword">using namespace</span> directives particularly
				well, so I would need to use a completely different (and potentially less reliable)
				approach for locating them in C++ code. Since I do next to no development in C++,
				I haven't had much incentive to make the effort so far. If you would like to use
				the add-in to sort <span class="codeKeyword">using namespace</span> directives in
				C++, please let me know. If there's enough demand, I'll try to make time for adding
				C++ support. </li>
			<li>
	The French translation is intended only as a verification that the add-in localization
	actually works. Unfortunately, I haven't been able to get my hands on a French drop
	of Visual Studio 2005 that supports add-ins, so the localization hasn't actually
	been tested yet. Assuming that it does actually work, any French-speaking users
	should please accept myNicole Calinoiu, October 2005 (last edited July 2009)</div>
</body>
</html>
